import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class ScoreManagementSystem {
    private List<Student> students = new ArrayList<>();
    private List<Course> courses = new ArrayList<>();
    private List<Score> scores = new ArrayList<>();
    private final String DATA_DIR = "data/"; // 数据存储目录

    // 初始化数据目录
    public ScoreManagementSystem() {
        File dir = new File(DATA_DIR);
        if (!dir.exists()) {
            dir.mkdirs();
        }
    }

    // 添加学生
    public void addStudent(Student student) {
        students.add(student);
    }

    // 添加课程
    public void addCourse(Course course) {
        courses.add(course);
    }

    // 添加成绩
    public void addScore(Student student, Course course, double score) {
        try {
            Score s = new Score(student, course, score);
            scores.add(s);
            System.out.println("成绩添加成功！");
        } catch (ScoreRangeException e) {
            System.out.println("成绩添加失败：" + e.getMessage());
        }
    }

    // 查询学生某门课程成绩
    public Score queryCourseScore(String studentId, String courseId) {
        for (Score score : scores) {
            if (score.getStudent().getStudentId().equals(studentId)
                    && score.getCourse().getCourseId().equals(courseId)) {
                return score;
            }
        }
        return null;
    }

    // 计算学生GPA
    public double calculateGPA(String studentId) {
        double totalGradePoints = 0;
        int totalCredits = 0;
        for (Score score : scores) {
            if (score.getStudent().getStudentId().equals(studentId)) {
                Course course = score.getCourse();
                totalCredits += course.getCredit();
                totalGradePoints += getGradePoint(score.getScore()) * course.getCredit();
            }
        }
        return totalCredits == 0 ? 0 : totalGradePoints / totalCredits;
    }

    // 分数转绩点
    private double getGradePoint(double score) {
        if (score >= 90) return 4.0;
        else if (score >= 80) return 3.0;
        else if (score >= 70) return 2.0;
        else if (score >= 60) return 1.0;
        else return 0.0;
    }

    // 保存数据到文件
    public void saveData() {
        // 保存学生
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(DATA_DIR + "students.dat"))) {
            oos.writeObject(students);
        } catch (IOException e) {
            System.out.println("保存学生数据失败：" + e.getMessage());
        }

        // 保存课程
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(DATA_DIR + "courses.dat"))) {
            oos.writeObject(courses);
        } catch (IOException e) {
            System.out.println("保存课程数据失败：" + e.getMessage());
        }

        // 保存成绩
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(DATA_DIR + "scores.dat"))) {
            oos.writeObject(scores);
        } catch (IOException e) {
            System.out.println("保存成绩数据失败：" + e.getMessage());
        }
        System.out.println("数据保存成功！");
    }

    // 从文件加载数据
    @SuppressWarnings("unchecked")
    public void loadData() {
        // 加载学生
        File studentFile = new File(DATA_DIR + "students.dat");
        if (studentFile.exists()) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(studentFile))) {
                students = (List<Student>) ois.readObject();
            } catch (IOException | ClassNotFoundException e) {
                System.out.println("加载学生数据失败：" + e.getMessage());
            }
        }

        // 加载课程
        File courseFile = new File(DATA_DIR + "courses.dat");
        if (courseFile.exists()) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(courseFile))) {
                courses = (List<Course>) ois.readObject();
            } catch (IOException | ClassNotFoundException e) {
                System.out.println("加载课程数据失败：" + e.getMessage());
            }
        }

        // 加载成绩
        File scoreFile = new File(DATA_DIR + "scores.dat");
        if (scoreFile.exists()) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(scoreFile))) {
                scores = (List<Score>) ois.readObject();
            } catch (IOException | ClassNotFoundException e) {
                System.out.println("加载成绩数据失败：" + e.getMessage());
            }
        }
        System.out.println("数据加载成功！");
    }

    // 主方法
    public static void main(String[] args) {
        ScoreManagementSystem system = new ScoreManagementSystem();
        Scanner scanner = new Scanner(System.in);

        // 先尝试加载已有数据
        system.loadData();

        // 初始化数据（如果数据为空）
        if (system.students.isEmpty() && system.courses.isEmpty() && system.scores.isEmpty()) {
            Student s1 = new Student("S001", "张三", "计算机一班");
            Student s2 = new Student("S002", "李四", "计算机二班");
            system.addStudent(s1);
            system.addStudent(s2);

            Course c1 = new Course("C001", "Java程序设计", 4);
            Course c2 = new Course("C002", "数据结构", 3);
            system.addCourse(c1);
            system.addCourse(c2);

            system.addScore(s1, c1, 85);
            system.addScore(s1, c2, 92);
            system.addScore(s2, c1, 78);
            system.addScore(s2, c2, 65);
            system.addScore(s1, c1, 105); // 测试异常

            // 保存初始化数据
            system.saveData();
        }

        // 查询成绩
        Score score = system.queryCourseScore("S001", "C001");
        if (score != null) {
            System.out.println("查询结果：" + score);
        } else {
            System.out.println("未找到该成绩");
        }

        // 计算GPA
        double gpa = system.calculateGPA("S001");
        System.out.println("张三的GPA：" + gpa);

        scanner.close();
    }
}